/*
 * Copyright (C) 2008-2011 CBDP Consortium
 * 
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.
 * 
 * This software consists of contributions made by many individuals, 
 * listed below:
 *
 * Author: 	Xabier Laiseca <xabier.laiseca@deusto.es>
 * 			David Ausín <david.ausin@deusto.es>
 */
package cbdp.server.contextreasoner.impl.contextmanager.online.model.wrappers;

import java.util.Collection;
import java.util.Vector;

import cbdp.server.contextreasoner.internal.InternalContextManager;
import cbdp.server.contextreasoner.model.GenericProperty;
import cbdp.server.contextreasoner.model.Instance;
import cbdp.server.contextreasoner.model.ObjectDatatypeProperty;
import cbdp.server.contextreasoner.model.PrimitiveDatatypeProperty;
import cbdp.server.contextreasoner.model.exceptions.InvalidDatatypeException;
import cbdp.server.contextreasoner.model.exceptions.NotExistingInstanceException;
import cbdp.server.contextreasoner.model.exceptions.NotExistingPropertyException;
import cbdp.server.contextreasoner.model.exceptions.NotExistingPropertyInstanceException;
import cbdp.server.contextreasoner.model.exceptions.PreviouslyDeteledPropertyException;

public class EagerSavingInstanceRuleLaunchingWrapper implements Instance
{
	private Instance wrapped;
	private InternalContextManager contextManager;
	
	public void setInstance(final Instance wrapped)
	{
		this.wrapped = wrapped;
	}
	
	public void setInternalContextManager(final InternalContextManager contextManager)
	{
		this.contextManager = contextManager;
	}

	@Override
	public String getIdentifier()
	{
		return wrapped.getIdentifier();
	}

	@Override
	public String getOntologyClass()
	{
		return wrapped.getOntologyClass();
	}

	@Override
	public void addObjectDatatypeProperty(String name, String objectName) throws NotExistingInstanceException, NotExistingPropertyException
	{
		wrapped.addObjectDatatypeProperty(name, objectName);
		launchRulesIfNotInExecution();
	}

	@Override
	public void addPrimitiveDatatypeProperty(String name, boolean value) throws NotExistingPropertyException, InvalidDatatypeException 
	{
		wrapped.addPrimitiveDatatypeProperty(name, value);
		launchRulesIfNotInExecution();
	}

	@Override
	public void addPrimitiveDatatypeProperty(String name, char value) throws NotExistingPropertyException, InvalidDatatypeException
	{
		wrapped.addPrimitiveDatatypeProperty(name, value);
		launchRulesIfNotInExecution();
	}

	@Override
	public void addPrimitiveDatatypeProperty(String name, double value) throws NotExistingPropertyException, InvalidDatatypeException
	{
		wrapped.addPrimitiveDatatypeProperty(name, value);
		launchRulesIfNotInExecution();
	}

	@Override
	public void addPrimitiveDatatypeProperty(String name, float value) throws NotExistingPropertyException, InvalidDatatypeException
	{
		wrapped.addPrimitiveDatatypeProperty(name, value);
		launchRulesIfNotInExecution();
	}

	@Override
	public void addPrimitiveDatatypeProperty(String name, int value) throws NotExistingPropertyException, InvalidDatatypeException
	{
		wrapped.addPrimitiveDatatypeProperty(name, value);
		launchRulesIfNotInExecution();
	}

	@Override
	public void addPrimitiveDatatypeProperty(String name, long value) throws NotExistingPropertyException, InvalidDatatypeException
	{
		wrapped.addPrimitiveDatatypeProperty(name, value);
		launchRulesIfNotInExecution();
	}

	@Override
	public void addPrimitiveDatatypeProperty(String name, String value) throws NotExistingPropertyException, InvalidDatatypeException
	{
		wrapped.addPrimitiveDatatypeProperty(name, value);
		launchRulesIfNotInExecution();
	}

	@Override
	public ObjectDatatypeProperty getObjectDatatypeProperty(String name) throws NotExistingPropertyException,NotExistingPropertyInstanceException
	{
		return addRuleLaunchingWrapToObjectDatatypeProperty(wrapped.getObjectDatatypeProperty(name));
	}

	@Override
	public Collection<ObjectDatatypeProperty> getObjectDatatypeProperties(String name) throws NotExistingPropertyException 
	{
		final Collection<ObjectDatatypeProperty> unwrappedProperties = wrapped.getObjectDatatypeProperties(name);
		final Vector<ObjectDatatypeProperty> wrappedProperties = new Vector<ObjectDatatypeProperty>();
		
		for(final ObjectDatatypeProperty property: unwrappedProperties)
		{
			wrappedProperties.add(addRuleLaunchingWrapToObjectDatatypeProperty(property));
		}
		
		return wrappedProperties;
	}
	
	private ObjectDatatypeProperty addRuleLaunchingWrapToObjectDatatypeProperty(final ObjectDatatypeProperty objectDatatypeProperty)
	{
		final EagerSavingObjectDatatypePropertyRuleLaunchingWrapper wrapper = new EagerSavingObjectDatatypePropertyRuleLaunchingWrapper();
		wrapper.setGenericProperty(objectDatatypeProperty);
		wrapper.setInternalContextManager(contextManager);
		return wrapper;
	}

	@Override
	public PrimitiveDatatypeProperty getPrimitiveDatatypeProperty(String name) throws NotExistingPropertyException, NotExistingPropertyInstanceException
	{
		return addRuleLaunchingWrapToPrimitiveDatatypeProperty(wrapped.getPrimitiveDatatypeProperty(name));
	}

	@Override
	public Collection<PrimitiveDatatypeProperty> getPrimitiveDatatypeProperties(String name) throws NotExistingPropertyException
	{
		final Collection<PrimitiveDatatypeProperty> unwrappedProperties = wrapped.getPrimitiveDatatypeProperties(name);
		final Vector<PrimitiveDatatypeProperty> wrappedProperties = new Vector<PrimitiveDatatypeProperty>();
		
		for(final PrimitiveDatatypeProperty property: unwrappedProperties)
		{
			wrappedProperties.add(addRuleLaunchingWrapToPrimitiveDatatypeProperty(property));
		}
		
		return wrappedProperties;
	}
	
	private PrimitiveDatatypeProperty addRuleLaunchingWrapToPrimitiveDatatypeProperty(final PrimitiveDatatypeProperty primitiveDatatypeProperty)
	{
		final EagerSavingPrimitiveDatatypePropertyRuleLaunchingWrapper wrapper = new EagerSavingPrimitiveDatatypePropertyRuleLaunchingWrapper();
		wrapper.setGenericProperty(primitiveDatatypeProperty);
		wrapper.setInternalContextManager(contextManager);
		return wrapper;
	}

	@Override
	public void deleteProperty(GenericProperty property) throws NotExistingPropertyException, PreviouslyDeteledPropertyException
	{
		wrapped.deleteProperty(property);
		launchRulesIfNotInExecution();
	}

	@Override
	public void deleteAllProperties(String name) throws NotExistingPropertyException
	{
		wrapped.deleteAllProperties(name);
		launchRulesIfNotInExecution();
	}
	
	private void launchRulesIfNotInExecution()
	{
		if (!contextManager.isInExecution())
		{
			contextManager.getGenericReasoner().launchRuleSets();
		}
	}

}
